home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- # MPing 1.1 - MacTCP Ping Tool
- #
- # Copyright © Apple Computer, Inc. 1990-1991
- # All rights reserved.
- #
- # Versions:
- # 1.1 September 25, 1991.
- #
- # File:
- # MPing.c
- #
- # Components:
- # AddressXlation.h
- # MacTCPCommonTypes.h
- # Makefile
- # MiscIPPB.h
- # MPing.c
- # MPing.h
- # MPing.r
- # MPingDlg.c
- # MPingExtern.h
- # MPingGlobals.h
- # MPingIcmp.c
- # MPingWindow.c
- # resolver.c
- ------------------------------------------------------------------------------*/
-
- #include <Values.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <DiskInit.h>
- #include <Packages.h>
- #include <Traps.h>
- #include <String.h>
- #include <StdLib.h>
- #include <StdIO.h>
- #include <CursorCtl.h>
- #include <Sound.h>
-
- #include "MacTCPCommonTypes.h"
- #include "MPing.h" /* bring in all the #defines for MPing */
- #include "AddressXlation.h"
- #include "MPingGlobals.h" /* bring in some structure definitions */
- #include "MPingExtern.h" /* all extern variables */
-
- SysEnvRec gMac; /* set up by Initialize */
-
- Boolean gHasWaitNextEvent; /* set up by Initialize */
-
- Boolean gInBackground; /* maintained by Initialize and DoEvent */
-
- Boolean gRunning=false; /* maintained by Initialize() and ICMP */
-
- Rect gStopRect; /* set up by Initialize */
- Rect gGoRect; /* set up by Initialize() */
- Rect gMsgRect; /* set up by initialize() - ICMP messages */
-
- short gFlipCursor=128; /* used as a cursor animation flag */
- short gCursorCount=0; /* animate the cursor during ping */
-
- unsigned long gTickCount; /* for timing */
-
- extern long gTempCount;
- extern Boolean gFixedNoOfPkts;
-
- void EventLoop( void );
- void DoEvent( EventRecord *event );
- void AdjustCursor( Point mouse, RgnHandle region );
- void GetGlobalMouse( Point *mouse );
- void DoUpdate( WindowPtr window );
- void DoActivate( WindowPtr window, Boolean becomingActive );
- void DoContentClick( WindowPtr window, EventRecord *event );
- void DrawWindow( WindowPtr window );
- void AdjustMenus( void );
- void DoMenuCommand( long menuResult );
- Boolean DoCloseWindow( WindowPtr window );
- void Terminate( void );
- void Initialize( void );
- Boolean GoGetRect( short rectID, Rect *theRect );
- void ForceEnvirons( void );
- Boolean IsAppWindow( WindowPtr window );
- Boolean IsDAWindow( WindowPtr window );
- Boolean TrapAvailable( short tNumber, TrapType tType );
- void AlertUser( short error );
- void WarnUser( short error );
- void DrawPingStatistics(WindowPtr window);
- void DrawOnScreen(void);
- void DrawPacketOnScreen(void);
- void DrawErrorMessageOnScreen(short errMsg);
- void DrawHostInfoOnScreen(void);
- void DoKeyDown( EventRecord *event );
- void DoSendIcmpPackets(void);
-
- extern void DoDialogItem(DialogPtr ldialog, short itemHit);
- extern DoInitDialog(DialogPtr ldialog);
- extern OSErr OpenResolver(char *fileName);
- extern OSErr CloseResolver(void);
- extern void AdjustHV(Boolean isVert, ControlHandle control, TEHandle docTE, Boolean canRedraw);
- extern void AdjustScrollValues(WindowPtr window, Boolean canRedraw);
- extern pascal void VActionProc(ControlHandle control, short part);
- extern void AdjustScrollbars(WindowPtr window, Boolean needsResize);
- extern void AdjustScrollSizes(WindowPtr window);
- extern void GetTERect(WindowPtr window, Rect *teRect);
- extern void AdjustViewRect(TEHandle docTE);
- extern void AdjustTE(WindowPtr window);
- extern void mycopy(char *dest, char *src, short noOfBytes);
- extern void SendIcmpEcho(void);
- extern void DoPingStop(DialogPtr ldialog, Handle itHandle);
-
- /* Define HiWrd and LoWrd macros for efficiency. */
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
-
- /* Define TopLeft and BotRight macros for convenience. Notice the implicit
- dependency on the ordering of fields within a Rect */
- #define TopLeft(aRect) (* (Point *) &(aRect).top)
- #define BotRight(aRect) (* (Point *) &(aRect).bottom)
-
-
- extern void _DataInit();
-
- /* This routine is part of the MPW runtime library. This external
- reference to it is done so that we can unload its segment, %A5Init. */
-
-
- #pragma segment Main
- main()
- {
- UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
-
- /* 1.01 - call to ForceEnvirons removed */
-
- /* If you have stack requirements that differ from the default,
- then you could use SetApplLimit to increase StackSpace at
- this point, before calling MaxApplZone. */
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- Initialize(); /* initialize the program */
- UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */
- EventLoop(); /* call the main event loop */
- }
-
-
- /* Get events forever, and handle them by calling DoEvent.
- Get the events by calling WaitNextEvent, if it's available, otherwise
- by calling GetNextEvent. Also call AdjustCursor each time through the loop. */
-
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
- Point mouse;
- WindowPtr window;
- DialogPtr ldialog;
- short itemHit;
- short titType;
- Handle titHandle;
- Rect titDispRect;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
- do {
- /* use WNE if it is available */
- if ( gHasWaitNextEvent ) {
- GetGlobalMouse(&mouse);
- AdjustCursor(mouse, cursorRgn);
- gotEvent = WaitNextEvent(everyEvent, &event, MAXLONG, cursorRgn);
- }
- else {
- SystemTask();
- gotEvent = GetNextEvent(everyEvent, &event);
- }
- if ( gotEvent ) {
- /* make sure we have the right cursor before handling the event */
- AdjustCursor(event.where, cursorRgn);
- DoEvent(&event);
- }
- if (window = FrontWindow()) {
- if (IsDialogEvent(&event)) {
- if (DialogSelect(&event, &ldialog, &itemHit))
- DoDialogItem(ldialog, itemHit);
- }
- if ((gSessionComplete == true) && (gRunning == true)) {
- GetDItem(window, PINGSTOP_BUTTON, &titType, &titHandle, &titDispRect);
- DoPingStop((DialogPtr) window, titHandle);
- }
- }
- DoSendIcmpPackets(); /* send icmp echo request to the destination host */
- } while ( true ); /* loop forever; we quit via ExitToShell */
- } /*EventLoop*/
-
-
- void DoSendIcmpPackets(void)
- {
- unsigned long myTickCount;
-
- if ((gQuietVerbose == false) && (gResponsePrinted == false) && (gRunning == true)) {
- DrawPacketOnScreen(); /* verbose mode, draw packet information */
- gResponsePrinted = true;
- }
- if ((gRunning == true) && (gSessionComplete == false)) { /* make sure we still want to send icmp echoes */
- myTickCount = TickCount();
- if (myTickCount >= (gTickCount+gWait)) {
- gTickCount = myTickCount;
- SendIcmpEcho();
- }
- }
- }
-
- /* Do the right thing for an event. Determine what kind of event it is, and call
- the appropriate routines. */
-
- #pragma segment Main
- void DoEvent(event)
- EventRecord *event;
- {
- short part, err;
- WindowPtr window;
- Boolean hit;
- char key;
- Point aPoint;
-
- switch ( event->what ) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch ( part ) {
- case inMenuBar: /* process a mouse menu command (if any) */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(event, window);
- break;
- case inContent:
- if ( window != FrontWindow() ) {
- SelectWindow(window);
- /*DoEvent(event);*/ /* use this line for "do first click" */
- } else
- DoContentClick(window, event);
- break;
- case inDrag: /* pass screenBits.bounds to get all gDevices */
- DragWindow(window, event->where, &qd.screenBits.bounds);
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- hit = TrackBox(window, event->where, part);
- if ( hit ) {
- SetPort(window); /* the window must be the current port... */
- EraseRect(&window->portRect); /* because of a bug in ZoomWindow */
- ZoomWindow(window, part, true); /* note that we invalidate and erase... */
- InvalRect(&window->portRect); /* to make things look better on-screen */
- }
- break;
- }
- break;
- case keyDown:
- case autoKey: /* check for menukey equivalents */
- key = event->message & charCodeMask;
- if ( event->modifiers & cmdKey ) { /* Command key down */
- if ( event->what == keyDown ) {
- AdjustMenus(); /* enable/disable/check menu items properly */
- DoMenuCommand(MenuKey(key));
- }
- }
- else ;
- break;
- case activateEvt:
- DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
- break;
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
- /* 1.01 - It is not a bad idea to at least call DIBadMount in response
- to a diskEvt, so that the user can format a floppy. */
- case diskEvt:
- if ( HiWord(event->message) != noErr ) {
- SetPt(&aPoint, kDILeft, kDITop);
- err = DIBadMount(aPoint, event->message);
- }
- break;
- case kOSEvent:
- /* 1.02 - must BitAND with 0x0FF to get only low byte */
- switch ((event->message >> 24) & 0x0FF) { /* high byte of message */
- case kSuspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (event->message & kResumeMask) == 0;
- DoActivate(FrontWindow(), !gInBackground);
- break;
- }
- break;
- }
- } /*DoEvent*/
-
-
- /* Change the cursor's shape, depending on its position. This also calculates the region
- where the current cursor resides (for WaitNextEvent). If the mouse is ever outside of
- that region, an event would be generated, causing this routine to be called,
- allowing us to change the region to the region the mouse is currently in. If
- there is more to the event than just “the mouse moved”, we get called before the
- event is processed to make sure the cursor is the right one. In any (ahem) event,
- this is called again before we fall back into WNE. */
-
- #pragma segment Main
- void AdjustCursor(mouse,region)
- Point mouse;
- RgnHandle region;
- {
- WindowPtr window;
- RgnHandle arrowRgn;
- RgnHandle curAnimRgn;
- Rect curAnimRect;
-
- window = FrontWindow(); /* we only adjust the cursor when we are in front */
- if ( (! gInBackground) && (! IsDAWindow(window)) ) {
- /* calculate regions for different cursor shapes */
- arrowRgn = NewRgn();
- curAnimRgn = NewRgn();
-
- /* start with a big, big rectangular region */
- SetRectRgn(arrowRgn, kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
-
- /* calculate curAnimRgn */
- if ( IsAppWindow(window) ) {
- curAnimRect = (*((DocumentPeek) window)->docTE)->viewRect;
- SetPort(window); /* make a global version of the viewRect */
- LocalToGlobal(&TopLeft(curAnimRect));
- LocalToGlobal(&BotRight(curAnimRect));
- RectRgn(curAnimRgn, &curAnimRect);
- SetOrigin(-window->portBits.bounds.left, -window->portBits.bounds.top);
- SectRgn(curAnimRgn, window->visRgn, curAnimRgn);
- SetOrigin(0, 0);
- }
-
- /* subtract other regions from arrowRgn */
- DiffRgn(arrowRgn, curAnimRgn, arrowRgn);
-
- /* change the cursor and the region parameter */
- if ( PtInRgn(mouse, curAnimRgn) && (gRunning == true) ) {
- gFlipCursor = (gFlipCursor == gLastCursor ? gFirstCuror : gFlipCursor+1);
- SetCursor(*GetCursor(gFlipCursor));
- SpinCursor(1); /* spin cursor by one frame */
- CopyRgn(curAnimRgn, region);
- } else {
- SetCursor(&qd.arrow);
- CopyRgn(arrowRgn, region);
- }
-
- /* get rid of our local regions */
- DisposeRgn(arrowRgn);
- DisposeRgn(curAnimRgn);
- }
- } /*AdjustCursor*/
-
-
- /* Get the global coordinates of the mouse. When you call OSEventAvail
- it will return either a pending event or a null event. In either case,
- the where field of the event record will contain the current position
- of the mouse in global coordinates and the modifiers field will reflect
- the current state of the modifiers. Another way to get the global
- coordinates is to call GetMouse and LocalToGlobal, but that requires
- being sure that thePort is set to a valid port. */
-
- #pragma segment Main
- void GetGlobalMouse(mouse)
- Point *mouse;
- {
- EventRecord event;
-
- OSEventAvail(kNoEvents, &event); /* we aren't interested in any events */
- *mouse = event.where; /* just the mouse position */
- } /*GetGlobalMouse*/
-
-
- /* This is called when an update event is received for a window.
- It calls DrawWindow to draw the contents of an application window.
- As an effeciency measure that does not have to be followed, it
- calls the drawing routine only if the visRgn is non-empty. This
- will handle situations where calculations for drawing or drawing
- itself is very time-consuming. */
-
- #pragma segment Main
- void DoUpdate(window)
- WindowPtr window;
- {
- if ( IsAppWindow(window) ) {
- BeginUpdate(window); /* this sets up the visRgn */
- if ( ! EmptyRgn(window->visRgn) ) { /* draw if updating needs to be done */
- UpdtDialog((DialogPtr) window, window->visRgn);
- TEUpdate(&(window->portRect), ((DocumentPeek) window)->docTE);
- FrameRect(&gMsgRect);
- }
- EndUpdate(window);
- }
- } /*DoUpdate*/
-
-
- /* This is called when a window is activated or deactivated.
- In Sample, the Window Manager's handling of activate and
- deactivate events is sufficient. Other applications may have
- TextEdit records, controls, lists, etc., to activate/deactivate. */
-
- #pragma segment Main
- void DoActivate(window, becomingActive)
- WindowPtr window;
- Boolean becomingActive;
- {
- Rect growRect;
-
- if ( IsAppWindow(window) ) {
- if ( becomingActive ) {
- /* do whatever you need to at activation */
- /* the growbox needs to be redrawn on activation: */
- /* adjust for the scrollbars */
- GetTERect( window, &growRect);
- InvalRect(&growRect);
- ShowControl( ((DocumentPeek) window)->docVScroll );
- DrawControls(window);
-
- }
- else {
- /* do whatever you need to at deactivation */
- HideControl( ((DocumentPeek) window)->docVScroll );
- }
- }
- } /*DoActivate*/
-
-
- /* This is called when a mouse-down event occurs in the content of a window.
- Other applications might want to call FindControl, TEClick, etc., to
- further process the click. */
-
- #pragma segment Main
- void DoContentClick(window, event)
- WindowPtr window;
- EventRecord *event;
- {
- Point mouse;
- ControlHandle control;
- short part, value;
- Boolean shiftDown;
- DocumentPeek doc;
- Rect teRect;
-
- if ( IsAppWindow(window) ) {
- SetPort(window);
- mouse = event->where; /* get the click position */
- GlobalToLocal(&mouse);
- doc = (DocumentPeek) window;
- GetTERect(window, &teRect);
- if ( PtInRect(mouse, &teRect) ) {
- /* see if we need to extend the selection */
- shiftDown = (event->modifiers & shiftKey) != 0; /* extend if Shift is down */
- } else {
- part = FindControl(mouse, window, &control);
- switch ( part ) {
- case 0: /* do nothing for viewRect case */
- break;
- case inThumb:
- value = GetCtlValue(control);
- part = TrackControl(control, mouse, nil);
- if ( part != 0 ) {
- value -= GetCtlValue(control);
- /* value now has CHANGE in value; if value changed, scroll */
- if ( value != 0 )
- if ( control == doc->docVScroll )
- TEScroll(0, value * (*doc->docTE)->lineHeight, doc->docTE);
- }
- break;
- default: /* they clicked in an arrow, so track & scroll */
- if ( control == doc->docVScroll )
- value = TrackControl(control, mouse, (ProcPtr) VActionProc);
- break;
- }
- }
- }
-
- } /*DoContentClick*/
-
-
- /* This is called for any keyDown or autoKey events, except when the
- Command key is held down. It looks at the frontmost window to decide what
- to do with the key typed. */
-
- #pragma segment Main
- void DoKeyDown(event)
- EventRecord *event;
- {
- WindowPtr window;
- char key;
- TEHandle te;
-
- window = FrontWindow();
- if ( IsAppWindow(window) ) {
- te = ((DocumentPeek) window)->docTE;
- key = event->message & charCodeMask;
- /* we have a char. for our window; see if we are still below TextEdit’s
- limit for the number of characters (but deletes are always rad) */
- if ( key == kDelChar ||
- (*te)->teLength - ((*te)->selEnd - (*te)->selStart) + 1 <
- kMaxTELength ) {
- TEKey(key, te);
- AdjustScrollbars(window, false);
- AdjustTE(window);
- } else
- AlertUser(sExceedChar);
- }
- } /*DoKeyDown*/
-
-
- /* Draw the contents of the application window. We do some drawing in color, using
- Classic QuickDraw's color capabilities. This will be black and white on old
- machines, but color on color machines. At this point, the window’s visRgn
- is set to allow drawing only where it needs to be done. */
-
- #pragma segment Main
- void DrawWindow(window)
- WindowPtr window;
- {
- SetPort(window);
-
- EraseRect(&window->portRect); /* clear out any garbage that may linger */
- DrawDialog((DialogPtr) window);
- DrawPingStatistics(window);
- } /*DrawWindow*/
-
-
- /* Enable and disable menus based on the current state.
- The user can only select enabled menu items. We set up all the menu items
- before calling MenuSelect or MenuKey, since these are the only times that
- a menu item can be selected. Note that MenuSelect is also the only time
- the user will see menu items. This approach to deciding what enable/
- disable state a menu item has the advantage of concentrating all
- the decision-making in one routine, as opposed to being spread throughout
- the application. Other application designs may take a different approach
- that is just as valid. */
-
- #pragma segment Main
- void AdjustMenus()
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMHandle(mFile);
- if ( IsDAWindow(window) ) /* we can allow desk accessories to be closed from the menu */
- EnableItem(menu, iClose);
- else
- DisableItem(menu, iClose); /* but not our traffic light window */
-
- menu = GetMHandle(mEdit);
- if ( IsDAWindow(window) ) { /* a desk accessory might need the edit menu… */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- } else { /* …but we don’t use it */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
- menu = GetMHandle(mIPOptions);
- if ( ! IsDAWindow(window) ) { /* if not a desk accessory window */
- EnableItem(menu, iRecordRoute);
- DisableItem(menu, iLooseSourceRR);
- DisableItem(menu, iStrictSourceRR);
- DisableItem(menu, iTimeStamp);
- DisableItem(menu, iSecurity);
- DisableItem(menu, iStreamID);
- }
- } /*AdjustMenus*/
-
-
- /* This is called when an item is chosen from the menu bar (after calling
- MenuSelect or MenuKey). It performs the right operation for each command.
- It is good to have both the result of MenuSelect and MenuKey go to
- one routine like this to keep everything organized. */
-
- #pragma segment Main
- void DoMenuCommand(menuResult)
- long menuResult;
- {
- short menuID; /* the resource ID of the selected menu */
- short menuItem; /* the item number of the selected menu */
- short itemHit;
- Str255 daName;
- short daRefNum;
- Boolean handledByDA;
-
- menuID = HiWord(menuResult); /* use macros for efficiency to... */
- menuItem = LoWord(menuResult); /* get menu item number and menu number */
- switch ( menuID ) {
- case mApple:
- switch ( menuItem ) {
- case iAbout: /* bring up alert for About */
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: /* all non-About items in this menu are DAs */
- /* type Str255 is an array in MPW 3 */
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch ( menuItem ) {
- case iClose:
- DoCloseWindow(FrontWindow());
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- case mEdit: /* call SystemEdit for DA editing & MultiFinder */
- handledByDA = SystemEdit(menuItem-1); /* since we don’t do any Editing */
- break;
- case mIPOptions:
- if (!gRunning) { /* we won't allow the user to change the */
- switch ( menuItem ) { /* options while we are sending icmp echoes */
- case iRecordRoute:
- gRR = !gRR;
- CheckItem(GetMHandle(mIPOptions), iRecordRoute, gRR);
- break;
- case iLooseSourceRR:
- gLSRR = !gLSRR;
- break;
- case iStrictSourceRR:
- gSSRR = !gSSRR;
- break;
- case iTimeStamp:
- gTimestamp = !gTimestamp;
- break;
- case iSecurity:
- gSecurity = !gSecurity;
- break;
- case iStreamID:
- gSID = !gSID;
- break;
- }
- }
- break;
- }
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /*DoMenuCommand*/
-
-
- /* Close a window. This handles desk accessory and application windows. */
-
- /* 1.01 - At this point, if there was a document associated with a
- window, you could do any document saving processing if it is 'dirty'.
- DoCloseWindow would return true if the window actually closed, i.e.,
- the user didn’t cancel from a save dialog. This result is handy when
- the user quits an application, but then cancels the save of a document
- associated with a window. */
-
- #pragma segment Main
- Boolean DoCloseWindow(window)
- WindowPtr window;
- {
- if ( IsDAWindow(window) )
- CloseDeskAcc(((WindowPeek) window)->windowKind);
- else if ( IsAppWindow(window) )
- CloseWindow(window);
- return true;
- } /*DoCloseWindow*/
-
-
- /* Clean up the application and exit. We close all of the windows so that
- they can update their documents, if any. */
-
- /* 1.01 - If we find out that a cancel has occurred, we won't exit to the
- shell, but will return instead. */
-
- #pragma segment Main
- void Terminate()
- {
- WindowPtr aWindow;
- Boolean closed;
- OSErr err;
-
- closed = true;
- do {
- aWindow = FrontWindow(); /* get the current front window */
- if (aWindow != nil)
- closed = DoCloseWindow(aWindow); /* close this window */
- }
- while (closed && (aWindow != nil));
- err = CloseResolver();
- if (closed)
- ExitToShell(); /* exit if no cancellation */
- } /*Terminate*/
-
-
- /* Set up the whole world, including global variables, Toolbox managers,
- and menus. We also create our one application window at this time.
- Since window storage is non-relocateable, how and when to allocate space
- for windows is very important so that heap fragmentation does not occur.
- Because Sample has only one window and it is only disposed when the application
- quits, we will allocate its space here, before anything that might be a locked
- relocatable object gets into the heap. This way, we can force the storage to be
- in the lowest memory available in the heap. Window storage can differ widely
- amongst applications depending on how many windows are created and disposed. */
-
- /* 1.01 - The code that used to be part of ForceEnvirons has been moved into
- this module. If an error is detected, instead of merely doing an ExitToShell,
- which leaves the user without much to go on, we call AlertUser, which puts
- up a simple alert that just says an error occurred and then calls ExitToShell.
- Since there is no other cleanup needed at this point if an error is detected,
- this form of error- handling is acceptable. If more sophisticated error recovery
- is needed, an exception mechanism, such as is provided by Signals, can be used. */
-
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- DialogPtr ldialog;
- long total, contig;
- EventRecord event;
- short count;
- OSErr err;
- Ptr storage;
- Rect destRect, viewRect;
- DocumentPeek doc;
-
- gInBackground = false;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- InitCursorCtl(nil);
-
- /* Call MPPOpen and ATPLoad at this point to initialize AppleTalk,
- if you are using it. */
- /* NOTE -- It is no longer necessary, and actually unhealthy, to check
- PortBUse and SPConfig before opening AppleTalk. The drivers are capable
- of checking for port availability themselves. */
-
- /* This next bit of code is necessary to allow the default button of our
- alert be outlined.
- 1.02 - Changed to call EventAvail so that we don't lose some important
- events. */
-
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
- /* Ignore the error returned from SysEnvirons; even if an error occurred,
- the SysEnvirons glue will fill in the SysEnvRec. You can save a redundant
- call to SysEnvirons by calling it after initializing AppleTalk. */
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
-
- /* Make sure that the machine has at least 128K ROMs. If it doesn't, exit. */
-
- if (gMac.machineType < 0) AlertUser(sWrongMachine);
-
- /* 1.02 - Move TrapAvailable call to after SysEnvirons so that we can tell
- in TrapAvailable if a tool trap value is out of range. */
-
- gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
-
- /* 1.01 - We used to make a check for memory at this point by examining ApplLimit,
- ApplicZone, and StackSpace and comparing that to the minimum size we told
- MultiFinder we needed. This did not work well because it assumed too much about
- the relationship between what we asked MultiFinder for and what we would actually
- get back, as well as how to measure it. Instead, we will use an alternate
- method comprised of two steps. */
-
- /* It is better to first check the size of the application heap against a value
- that you have determined is the smallest heap the application can reasonably
- work in. This number should be derived by examining the size of the heap that
- is actually provided by MultiFinder when the minimum size requested is used.
- The derivation of the minimum size requested from MultiFinder is described
- in Sample.h. The check should be made because the preferred size can end up
- being set smaller than the minimum size by the user. This extra check acts to
- insure that your application is starting from a solid memory foundation. */
-
- if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap)
- AlertUser(sAppMemSmall);
-
- /* Next, make sure that enough memory is free for your application to run. It
- is possible for a situation to arise where the heap may have been of required
- size, but a large scrap was loaded which left too little memory. To check for
- this, call PurgeSpace and compare the result with a value that you have determined
- is the minimum amount of free memory your application needs at initialization.
- This number can be derived several different ways. One way that is fairly
- straightforward is to run the application in the minimum size configuration
- as described previously. Call PurgeSpace at initialization and examine the value
- returned. However, you should make sure that this result is not being modified
- by the scrap's presence. You can do that by calling ZeroScrap before calling
- PurgeSpace. Make sure to remove that call before shipping, though. */
-
- /* ZeroScrap(); */
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace) AlertUser(sAppMemSmall);
-
- /* The extra benefit to waiting until after the Toolbox Managers have been initialized
- to check memory is that we can now give the user an alert to tell him/her what
- happened. Although it is possible that the memory situation could be worsened by
- displaying an alert, MultiFinder would gracefully exit the application with
- an informative alert if memory became critical. Here we are acting more
- in a preventative manner to avoid future disaster from low-memory problems. */
-
- gRunning = false; /* initialize the icmp echo sending flag */
- /* we will allocate our own window storage instead of letting the Window
- Manager do it because GetNewWindow may load in temp. resources before
- making the NewPtr call, and this can lead to heap fragmentation. */
- storage = NewPtr(sizeof(DocumentRecord));
- if ( storage == nil ) AlertUser(sAppMemSmall);
- if ( !GoGetRect(rMsgRect, &gMsgRect) )
- AlertUser(sNoRectRes); /* the ICMP message rectangle */
- ldialog = GetNewDialog(rDialog, storage, (WindowPtr) -1);
-
- ShowWindow(ldialog);
- SetPort(ldialog);
- DoInitDialog(ldialog);
- TextMode(srcCopy);
- TextFont(monaco);
- TextSize(9);
- doc = (DocumentPeek) ldialog;
- GetTERect(ldialog, &viewRect);
- destRect = viewRect;
- doc->docTE = TENew(&destRect, &viewRect);
- if (doc->docTE == nil) AlertUser(sNoTERes);
- AdjustViewRect(doc->docTE);
- TEAutoView(true, doc->docTE);
- doc->docVScroll = GetNewControl(rVScroll, (WindowPtr) doc);
- if (doc->docVScroll == nil) AlertUser(sNoVScrollBar);
- AdjustScrollValues(ldialog, false);
- ShowWindow(ldialog);
-
- menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */
- if ( menuBar == nil ) AlertUser(sNoMenuBar);
- SetMenuBar(menuBar); /* install menus */
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
- DrawMenuBar();
-
- err = OpenResolver(nil);
- if (err != noErr) {
- SysBeep(5); SysBeep(10); SysBeep(55);
- AlertUser(sResolverErr); /* fatal error */
- }
- } /*Initialize*/
-
-
- /* This utility loads the global rectangles that are used by the window
- drawing routines. It shows how the resource manager can be used to hold
- values in a convenient manner. These values are then easily altered without
- having to re-compile the source code. In this particular case, we know
- that this routine is being called at initialization time. Therefore,
- if a failure occurs here, we will assume that the application is in such
- bad shape that we should just exit. Your error handling may differ, but
- the check should still be made. */
-
- #pragma segment Initialize
- Boolean GoGetRect(rectID,theRect)
- short rectID;
- Rect *theRect;
- {
- Handle resource;
-
- resource = GetResource('RECT', rectID);
- if ( resource != nil ) {
- *theRect = **((Rect**) resource);
- return true;
- }
- else
- return false;
- } /* GoGetRect */
-
-
- /* Check to see if a window belongs to the application. If the window pointer
- passed was NIL, then it could not be an application window. WindowKinds
- that are negative belong to the system and windowKinds less than userKind
- are reserved by Apple except for windowKinds equal to dialogKind, which
- mean it is a dialog.
- 1.02 - In order to reduce the chance of accidentally treating some window
- as an AppWindow that shouldn't be, we'll only return true if the windowkind
- is userKind. If you add different kinds of windows to Sample you'll need
- to change how this all works. */
-
- #pragma segment Main
- Boolean IsAppWindow(window)
- WindowPtr window;
- {
- short windowKind;
-
- if ( window == nil )
- return false;
- else { /* application windows have windowKinds = userKind (8) */
- windowKind = ((WindowPeek) window)->windowKind;
- return (windowKind = userKind);
- }
- } /*IsAppWindow*/
-
-
- /* Check to see if a window belongs to a desk accessory. */
-
- #pragma segment Main
- Boolean IsDAWindow(window)
- WindowPtr window;
- {
- if ( window == nil )
- return false;
- else /* DA windows have negative windowKinds */
- return ((WindowPeek) window)->windowKind < 0;
- } /*IsDAWindow*/
-
-
- /* Check to see if a given trap is implemented. This is only used by the
- Initialize routine in this program, so we put it in the Initialize segment.
- The recommended approach to see if a trap is implemented is to see if
- the address of the trap routine is the same as the address of the
- Unimplemented trap. */
- /* 1.02 - Needs to be called after call to SysEnvirons so that it can check
- if a ToolTrap is out of range of a pre-MacII ROM. */
-
- #pragma segment Initialize
- Boolean TrapAvailable(tNumber,tType)
- short tNumber;
- TrapType tType;
- {
- if ( ( tType == ToolTrap ) &&
- ( gMac.machineType > envMachUnknown ) &&
- ( gMac.machineType < envMacII ) ) { /* it's a 512KE, Plus, or SE */
- tNumber = tNumber & 0x03FF;
- if ( tNumber > 0x01FF ) /* which means the tool traps */
- tNumber = _Unimplemented; /* only go to 0x01FF */
- }
- return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
- } /*TrapAvailable*/
-
-
- /* Display an alert that tells the user an error occurred, then exit the program.
- This routine is used as an ultimate bail-out for serious errors that prohibit
- the continuation of the application. Errors that do not require the termination
- of the application should be handled in a different manner. Error checking and
- reporting has a place even in the simplest application. The error number is used
- to index an 'STR#' resource so that a relevant message can be displayed. */
-
- #pragma segment Main
- void AlertUser(short error)
- short error;
- {
- short itemHit;
- Str255 message;
-
- SetCursor(&qd.arrow);
- GetIndString(message, rErrorStrings, error);
- ParamText(message, "", "", "");
- itemHit = Alert(rUserAlert, nil);
- ExitToShell();
- } /* AlertUser */
-
- #pragma segment Main
- void WarnUser(short error)
- short error;
- {
- short itemHit;
- Str255 message;
-
- SetCursor(&qd.arrow);
- GetIndString(message, rErrorStrings, error);
- ParamText(message, "", "", "");
- itemHit = Alert(rUserAlert, nil);
- } /* WarnUser */
-
- #pragma segment Main
- void DrawPingStatistics(window)
- WindowPtr window;
- {
- Rect tRect;
- TEHandle te;
-
- FrameRect(&gMsgRect);
-
- te = ((DocumentPeek) window)->docTE;
- tRect = (**te).viewRect;
-
- EraseRect(&tRect);
- TEUpdate(&tRect, te);
- }
-
- #pragma segment Main
- void DrawOnScreen(void)
- {
- WindowPtr window;
- TEHandle te;
- char ourString1[255], ourString2[255], tIPAddrStr[5];
- unsigned long *tIPAddrLPtr;
- Rect teRect;
- short tindex, totlength;
-
- if (window = FrontWindow())
- if ( IsAppWindow(window) ) {
- SetPort(window);
- BeginUpdate(window);
- te = ((DocumentPeek) window)->docTE;
- teRect = (**te).viewRect;
-
- getindstring(ourString1, rErrorStrings, sPktInfo);
- sprintf(ourString2, "%d/%d/%d/%d\n", gIcmpStat.totPktOut,
- gIcmpStat.totPktIn, gIcmpStat.totPktBad, gIcmpStat.pktLoss);
- strcat(ourString1, ourString2);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
- getindstring(ourString1, rErrorStrings, sTimeInfo);
- sprintf(ourString2, "%u/%u/%u\n",
- gIcmpStat.minTime, gIcmpStat.avgTime, gIcmpStat.maxTime);
- strcat(ourString1, ourString2);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
-
- if (gRR) {
- if (gIPOptionResponse[0] != '\0') {
- getindstring(ourString1, rErrorStrings, sRecordedRoute);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
- tIPAddrLPtr = (unsigned long *) tIPAddrStr;
- tindex = 3; /* format of the Record Route option blk */
- totlength = gIPOptionResponse[2] - 1;
- while((tindex < totlength) && (tindex < MAX_OPT_SIZE)) {
- mycopy(tIPAddrStr, &gIPOptionResponse[tindex], 4);
- AddrToStr(*tIPAddrLPtr, ourString1);
- strcat(ourString1, "\n");
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
- tindex += 4;
- }
- }
- else {
- getindstring(ourString1, rErrorStrings, sNoRoutesRecorded);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
- }
- }
- getindstring(ourString1, rErrorStrings, sPingTail);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
- GetTERect(window, &teRect);
- teRect.right += kScrollbarWidth; /* for scroll bar */
- InvalRect(&teRect);
- TEUpdate(&teRect, te);
- AdjustScrollbars(window, false);
- AdjustTE(window);
- EndUpdate(window);
- }
- }
-
- #pragma segment Main
- void DrawPacketOnScreen(void)
- {
- WindowPtr window;
- TEHandle te;
- char ourString1[255], ourString2[255];
- Rect teRect;
-
- if (gResponseStatus.pkt_no != 0)
- if (window = FrontWindow())
- if ( IsAppWindow(window) ) {
- SetPort(window);
- BeginUpdate(window);
- te = ((DocumentPeek) window)->docTE;
- teRect = (**te).viewRect;
-
- if (gResponseStatus.response_ok == true) {
- getindstring(ourString1, rErrorStrings, sSuccessPktStatus);
- sprintf(ourString2, "%d/%d/%d\n", gResponseStatus.pkt_no,
- gResponseStatus.rt_time, gResponseStatus.pkt_len);
- }
- else {
- getindstring(ourString1, rErrorStrings, sTimeoutPktStatus);
- sprintf(ourString2, "%d\n", gResponseStatus.pkt_no);
- }
- strcat(ourString1, ourString2);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
-
- GetTERect(window, &teRect);
- teRect.right += kScrollbarWidth; /* for scroll bar */
- InvalRect(&teRect);
- TEUpdate(&teRect, te);
- AdjustScrollbars(window, false);
- AdjustTE(window);
- EndUpdate(window);
- gResponseStatus.pkt_no = 0;
- gResponseStatus.rt_time = 0;
- gResponseStatus.pkt_len = 0;
- gResponseStatus.response_ok = true;
- }
- }
-
- #pragma segment Main
- void DrawErrorMessageOnScreen(errMsg)
- short errMsg;
- {
- WindowPtr window;
- TEHandle te;
- char ourString1[255];
- Rect teRect;
-
- if (window = FrontWindow())
- if ( IsAppWindow(window) ) {
- SetPort(window);
- BeginUpdate(window);
- te = ((DocumentPeek) window)->docTE;
- teRect = (**te).viewRect;
-
- getindstring(ourString1, rErrorStrings, errMsg);
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
-
- GetTERect(window, &teRect);
- teRect.right += kScrollbarWidth; /* for scroll bar */
- InvalRect(&teRect);
- TEUpdate(&teRect, te);
- AdjustScrollbars(window, false);
- AdjustTE(window);
- EndUpdate(window);
- }
- }
-
- #pragma segment Main
- void DrawHostInfoOnScreen(void)
- {
- WindowPtr window;
- TEHandle te;
- char ourString1[255];
- char ourString2[255];
- Rect teRect;
-
- if (window = FrontWindow()) {
- if ( IsAppWindow(window) ) {
- SetPort(window);
- BeginUpdate(window);
- te = ((DocumentPeek) window)->docTE;
- teRect = (**te).viewRect;
-
- getindstring(ourString1, rErrorStrings, sSourceAddress);
- strcat(ourString1, "[");
- strcat(ourString1, gSourceAddress);
- strcat(ourString1, "] --> ");
-
- getindstring(ourString2, rErrorStrings, sDestinationAddress);
- strcat(ourString1, ourString2);
-
- if ((gHostAddress[0] < '0') || (gHostAddress[0] > '9')) {
- strcat(ourString1, gHostAddress);
- strcat(ourString1, " ");
- }
- strcat(ourString1, "[");
- strcat(ourString1, gDestAddress);
- strcat(ourString1, "]\n");
-
- TEInsert((Ptr) ourString1, strlen(ourString1), te);
-
- GetTERect(window, &teRect);
- teRect.right += kScrollbarWidth;
- InvalRect(&teRect);
- TEUpdate(&teRect, te);
- AdjustScrollbars(window, false);
- AdjustTE(window);
- EndUpdate(window);
- }
- }
- }
-